541. 反转字符串 II

541. 反转字符串 II

题目链接
代码随想录

分析

这个题直接用模拟即可,直接用 while 循环,i 为每次循环处理的子串的起点,初始值为 0,每次循环,我们都能确定这一轮的起点,当我们确定了起点 i 之后,需要反转的字符串的索引的终点的位置,其实是 i+k-1chars.length-1 中小的那一个,然后确定 i+k+k-1chars.length-1 中那个小,然后以这个值 +1,作为 i 的下一个值,再次循环。
有一个特别需要注意的地方,当字符串的起点为 i 的时候,反转从 i 开始的前 k 个字符串的范围是 [i,i+k-1],而不是 [i,i+k],这个需要特别注意。

解题

public String reverseStr(String s, int k) {
    char[] chars = s.toCharArray();
    int i=0;
    while(i<chars.length){
        int half = i+k-1;
        // 需要反转的部分
        int roundEnd = half<=chars.length-1?half:chars.length-1;
        int end = i+k+k-1;
        // 下一次处理的起点
        int next =  end<=chars.length-1?end:chars.length-1;
        int roundStart = i;
        for(;roundStart<roundEnd;){
            char temp = chars[roundStart];
            chars[roundStart]=chars[roundEnd];
            chars[roundEnd]=temp;
            roundStart++;
            roundEnd--;
        }
        i=next+1;
    }
    return new String(chars);        
}

其实还有一个更简单的视角,就是直接累加 k 这个步长(step)因为我们可以注意到,走奇数步的时候,这一步内的元素就得反转,走偶数步的就不需要

public String reverseStr(String s, int k) {
    char[] schar = s.toCharArray();
    int step=1;
    while(true){
	    // 走的步数是奇数步才需要反转
        if(step%2==1){
            // 开始交换
            // 刚走的这一步的起点在数组中的索引
            int left = k*(step-1);
            // 刚走的这一步的终点在数组中的索引
            int right=(step*k-1)<schar.length?(step*k-1):schar.length-1;
            // 开始交换                
            while(left<right){
                char temp = schar[left];
                schar[left] = schar[right];
                schar[right] = temp;
                left++;
                right--;
            }
        }
        // 刚走的这一步是否已经走出了数组
        if((step*k-1)>schar.length-1){
            break;
        }
        // 没有走出数组,则继续走
        step++;
    }
    return new String(schar);
}

相关题

344. 反转字符串